package org.mozhu.mboot.core.file.cloud.qiniu;

import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import lombok.extern.slf4j.Slf4j;
import org.mozhu.mboot.core.file.cloud.CloudFileService;
import org.mozhu.mboot.core.json.JSON;
import org.springframework.util.Assert;

import java.io.File;
import java.util.List;

@Slf4j
public abstract class QiniuCloudFileService implements CloudFileService {
    public static final String FILE_CLOUD_QINIU_BUCKET = "file.cloud.qiniu.bucket";
    public static final String FILE_CLOUD_QINIU_ACCESS_KEY = "file.cloud.qiniu.access.key";
    public static final String FILE_CLOUD_QINIU_SECRET_KEY = "file.cloud.qiniu.secret.key";

    private UploadManager uploadManager = new UploadManager(new Configuration(getZone()));

    @Override
    public void batchDelete(List<String> keys) {
        for (String key : keys) {
            delete(key);
        }
    }

    @Override
    public void put(String key, File file) {
        String bucket = getBucket();
        try {
            log.info("Put for file bucket[{}], key[{}], filePath[{}]", bucket, key, file.getAbsolutePath());
            String upToken = getUploadToken(bucket, key);
            Response response = uploadManager.put(file, key, upToken);
            DefaultPutRet putRet = JSON.toJavaObject(response.bodyString(), DefaultPutRet.class);
            Assert.isTrue(key.equals(putRet.key), "return key not match");
        } catch (Exception e) {
            log.error("Put error for file bucket[" + bucket + "], key[" + key + "]", e);
            throw new RuntimeException("Put error", e);
        }
    }

    @Override
    public void put(String key, String filePath) {
        String bucket = getBucket();
        try {
            log.info("Put for file bucket[{}], key[{}], filePath[{}]", bucket, key, filePath);
            String upToken = getUploadToken(bucket, key);
            Response response = uploadManager.put(filePath, key, upToken);
            DefaultPutRet putRet = JSON.toJavaObject(response.bodyString(), DefaultPutRet.class);
            Assert.isTrue(key.equals(putRet.key), "return key not match");
        } catch (Exception e) {
            log.error("Put error for file bucket[" + bucket + "], key[" + key + "]", e);
            throw new RuntimeException("Put error", e);
        }
    }

    @Override
    public void delete(String key) {
        try {
            BucketManager bucketManager = new BucketManager(getAuth(), new Configuration(getZone()));
            bucketManager.delete(getBucket(), key);
        } catch (QiniuException e) {
            log.error("Delete error for file bucket[" + getBucket() + "], key[" + key + "]", e);
            throw new RuntimeException("Delete error", e);
        }
    }

    private String getUploadToken(String bucket, String key) {
        Auth auth = getAuth();
        String upToken = auth.uploadToken(bucket, key);
        return upToken;
    }

    private Auth getAuth() {
        return Auth.create(getAccessKey(), getSecretKey());
    }

    public Zone getZone() {
        return Zone.autoZone();
    }

    public abstract String getBucket();

    public abstract String getAccessKey();

    public abstract String getSecretKey();

}
